const isType = (obj, type) => {
    if (typeof obj !== 'object') return false;
    // 判断数据类型的经典方法：
    const typeString = Object.prototype.toString.call(obj);
    let flag;
    switch (type) {
        case 'Array':
            flag = typeString === '[object Array]';
            break;
        case 'Date':
            flag = typeString === '[object Date]';
            break;
        case 'RegExp':
            flag = typeString === '[object RegExp]';
            break;
        default:
            flag = false;
    }
    return flag;
};
const getRegExp = re => {
    let flags = '';
    if (re.global) flags += 'g';
    if (re.ignoreCase) flags += 'i';
    if (re.multiline) flags += 'm';
    return flags;
};

/**
 * 深克隆对象
 * @param  parent object 需要进行克隆的对象
 * @return 深克隆后的对象
 */
export default function deepClone(parent) {
    const parents = [];
    const children = [];
    const _clone = parent => {
        if (parent === null) return null;
        if (typeof parent !== 'object') return parent;
        let child, proto;
        if (isType(parent, 'Array')) {
            child = [];
        } else if (isType(parent, 'RegExp')) {
            child = new RegExp(parent.source, getRegExp(parent));
            if (parent.lastIndex) child.lastIndex = parent.lastIndex;
        } else if (isType(parent, 'Date')) {
            child = new Date(parent.getTime());
        } else {
            proto = Object.getPrototypeOf(parent);
            child = Object.create(proto);
        }
        // 处理循环引用
        const index = parents.indexOf(parent);
        if (index !== -1) {
            return children[index];
        }
        parents.push(parent);
        children.push(child);
        for (let i in parent) {
            child[i] = _clone(parent[i]);
        }
        return child;
    };
    return _clone(parent);
}